#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>

#define BUFSIZE 1000
#define LISTENPORT 50081
#define MAXPENDING 5

void Die(char *mess, int sock) { perror(mess); close(sock); exit(1); }
void PrintStatus(char *mess) { char outmess[BUFSIZE]; sprintf(outmess,"%s\n",mess); fprintf(stdout,outmess); fflush(stdout); }
void timestrings(char *retstring);

char connected_server[BUFSIZE];

void timestrings(char *retstring){
/*   time_t time_now; */
/*   struct tm *time_ptr; */

/*   time(&time_now); */
/*   time_ptr=gmtime(&time_now); */
/*   strftime(buf,BUFSIZE,"%d/%m/%Y %H:%M:%S",time_ptr); */
  sprintf(retstring,"Message received from %s",connected_server);
}

int main(int argc, char *argv[]){
  int serversock, clientsock,received=-1,recvlen=0,sndlen=0;
  struct sockaddr_in mesgserver, mesgclient;
  char buffer[BUFSIZE],tbuf[BUFSIZE];

  /* Create the TCP socket */
  if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    Die("Failed to create socket",serversock);

  /* Construct the server sockaddr_in structure */
  memset(&mesgserver, 0, sizeof(mesgserver));       /* Clear struct */
  mesgserver.sin_family = AF_INET;                  /* Internet/IP */
  mesgserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* Incoming addr */
  mesgserver.sin_port = htons(LISTENPORT);          /* server port */
  
  /* Bind the server socket */
  if (bind(serversock, (struct sockaddr *) &mesgserver,
	   sizeof(mesgserver)) < 0)
    Die("Failed to bind the server socket",serversock);

  /* Listen on the server socket */
  if (listen(serversock, MAXPENDING) < 0)
    Die("Failed to listen on server socket",serversock);
           
  /* Run until cancelled */
  while (1) {
    unsigned int clientlen = sizeof(mesgclient);
    /* Wait for client connection */
    if ((clientsock =
	 accept(serversock, (struct sockaddr *) &mesgclient,
		&clientlen)) < 0){
      PrintStatus("Failed to accept client connection");
      continue;
    }
    if ((received=recv(clientsock,buffer,BUFSIZE,0))<0){
      PrintStatus("Failed to receive initial bytes from client");
      continue;
    }
    buffer[received]='\0';
    strcpy(connected_server,inet_ntoa(mesgclient.sin_addr));
    if (strcmp(buffer,"Attempting to register this machine as a message client...")==0){
      /* we're being asked to show that we're a listener for the recorder server */
      /* the correct response is "client acknowledged" */
      strcpy(tbuf,"client acknowledged");
      sndlen=(int)strlen(tbuf);
      if (send(clientsock,tbuf,sndlen+1,0)!=sndlen+1){
	PrintStatus("Failed to properly acknowledge server");
      } else {
	PrintStatus("Server acknowledgement completed.");
      }
    } else {
      /* print the message */
      timestrings(tbuf);
      PrintStatus(tbuf);
      recvlen=strlen(buffer);
      PrintStatus(buffer);
      /* acknowledge receipt of the message */
      strcpy(tbuf,"client acknowledged");
      sndlen=(int)strlen(tbuf);
      if (send(clientsock,tbuf,sndlen+1,0)!=sndlen+1){
	PrintStatus("Failed to properly acknowledge server");
      }
    }
    close(clientsock);
  }
}
